/*  
 * 文 件    名: DXApplication.java
 * 创建日期: 2012-9-17
 * 版          权: Epro Technologies Co., Ltd. Copyright 2011-2012,  All rights reserved
 * 作          者: hjd008
 */

package com.weipu.common;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
import android.support.multidex.MultiDex;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.umeng.analytics.MobclickAgent;
import com.weipu.common.constants.DxConfig;
import com.weipu.common.util.GlobalConfig;
import com.weipu.common.util.Logger;
import com.weipu.common.util.utils.SPUtils;
import com.weipu.common.util.utils.Utils;
import com.weipu.dx_lib.R;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import cn.jpush.android.api.JPushInterface;

/**
 * 
 * 任意类中使用DXApplication.getInstance()来获取应用程序Context。
 * 
 * @version [版本号, 2012-9-17]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 * 
 * @author hjd008
 */
public class DXApplication extends Application
{
    
    private static final String TAG = DXApplication.class.getSimpleName();
    
    private static DXApplication instance;
    
    /**
     * @Fields serviceIntents : 启动服务的容器
     */
    private List<Intent> serviceIntents = null;
    
    /**
     * @Fields activityLists : 栈内Activity实例列表
     */
    private List<Activity> activityLists = null;
    
    /**
     * @Fields isNetOk : 网络是否可用
     */
    // public static boolean isNetOk = false;
    
//    private ConnectionFactoryRegistry connectionFactoryRegistry;
    
//    private SQLiteOpenHelper repositoryHelper;
    
    public static DXApplication getContext()
    {
        return instance;
    }
    
    /**
     * 应用开启时调用这个方法
     */
    @Override
    public void onCreate()
    {
        Logger.d(TAG, "DXApplication onCreate.");
        super.onCreate();

        //设置不打印log
        Logger.updateLogEnable(false);
        setException();
        init();
        initUtil();
        initConfig();
        initImageLoaderData();
        // create a new ConnectionFactoryLocator and populate it with Facebook
        // ConnectionFactory
//        this.connectionFactoryRegistry = new ConnectionFactoryRegistry();
//        this.connectionFactoryRegistry.addConnectionFactory(new FacebookConnectionFactory(getFacebookAppId(),
//            getFacebookAppSecret()));
        
        // set up the database and encryption
//        this.repositoryHelper = new SQLiteConnectionRepositoryHelper(this);
//        this.connectionRepository =
//            new SQLiteConnectionRepository(this.repositoryHelper, this.connectionFactoryRegistry,
//                AndroidEncryptors.text("password", "5c0744940b5c369b"));
        
        GlobalConfig.getInstance().setCheckSSL(true);
    }

    @Override
    protected void attachBaseContext(final Context base) {
        super.attachBaseContext(base);
        //分割Dex文件，避免方法数超过65535
        MultiDex.install(this);
    }

    private void initUtil() {
        Utils.init(this);
        new SPUtils(getResources().getString(R.string.app_name_en));

    }

    private void initConfig() {

        // config配置文件的修改
        int id = getResources().getIdentifier("config", "raw", getPackageName());
        if (id == 0) {
            return;
        }

        InputStream iStream = getResources().openRawResource(id);

        DxConfig.init(iStream);

    }
    
    private void initImageLoaderData(){
    	 //创建默认的ImageLoader配置参数   
//        ImageLoaderConfiguration configuration = ImageLoaderConfiguration  
//     		            .createDefault(this); 
        
        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this)
             
                .diskCacheSize(50 * 1024 * 1024)
                .build();
        
     	//Initialize ImageLoader with configuration.   
     	ImageLoader.getInstance().init(configuration);  
    }
    
    //设置全局异常，避免FC问题
    public void setException()
    {
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
        {
            @Override
            public void uncaughtException(Thread thread, Throwable ex)
            {
                ex.printStackTrace();
                Logger.e("Error ", "uncat Exception, thread: " + thread.getId() + "," + thread.getName()+ex.toString());
                MobclickAgent.reportError(getApplicationContext(), ex);
                MobclickAgent.onKillProcess(getApplicationContext());
                System.exit(1);
            }
        });
    }
    
    /**
     * 初始化方法实现
     */
    private void init()
    {
        // 全局上下文实例
        instance = this;
        // 初始化活动容器
        activityLists = new ArrayList<Activity>();
        
        // 初始化Service容器
        serviceIntents = new ArrayList<Intent>();
        
        //初始化极光推送SDK
        JPushInterface.setDebugMode(true);
        JPushInterface.init(getApplicationContext());
        //异步执行启动任务   
//        ThreadUtil.getInstance().getThreadPoolIntance().execute(new Runnable()
//        {
//            @Override
//            public void run()
//            {
//                // 执行程序启动任务
//                StartupTask firstTask = new StartupTask();
//                firstTask.setDelay(ConfigUtil.getInstance().getConfig().getStartupConfig().getStartupDelay() * 3 / 2);
//                TaskExecutor.doTaskInBackground(firstTask);
//            }
//        });//取消app预加载功能  降低服务器压力
        
        // When dry run is set, hits will not be dispatched, but will still be logged as
        // though they were dispatched.
//        GoogleAnalytics.getInstance(this).setDryRun(false);
    }
    
    /**
     * 添加activity
     * 
     * @param activity
     *            [参数说明]
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public void addActivityToLists(Activity activity)
    {
        if (activity != null)
        {
            activityLists.add(activity);
        }
    }
    
    /**
     * remove activity
     * 
     * @param activity
     *            [参数说明]
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public void removeActivityFromLists(Activity activity)
    {
        if (activity != null&&activityLists.contains(activity))
        {
        	Logger.i(TAG, "remove: "+activityLists.contains(activity)+" "+activity);
            activityLists.remove(activity);
        }
    }
    
    /**
     * 清除所有activity
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public void finishActivityLists()
    {
        if (activityLists != null && activityLists.size() != 0)
        {
            for (int i = 0; i < activityLists.size(); i++)
            {
                if (activityLists.get(i) != null && !activityLists.get(i).isFinishing())
                {
                    ((Activity)activityLists.get(i)).finish();
                }
            }
            
        }
    }
    
    /**
     * 统一开启服务方法实现
     * 
     * @param cls
     * @param bundle
     *            [参数说明]
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public void startAppService(Class<?> cls, Bundle bundle)
    {
        Intent intent = new Intent(getApplicationContext(), cls);
        
        // 此处bundle值考虑到给服务传递参数时使用，如不传递参数，可置null
        if (bundle != null)
        {
            intent.putExtra("bundle", bundle);
        }
        serviceIntents.add(intent);
        startService(intent);
    }
    
    /**
     * 统一开启服务方法实现
     * 
     * @param intent
     *            [参数说明]
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public void startAppService(Intent intent)
    {
        serviceIntents.add(intent);
        startService(intent);
    }
    
    /**
     * 统一关闭服务方法实现
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public void stopAppService()
    {
        if (serviceIntents != null && serviceIntents.size() != 0)
        {
            for (int i = 0; i < serviceIntents.size(); i++)
            {
                if (serviceIntents.get(i) != null)
                {
                    stopService(serviceIntents.get(i));
                }
            }
        }
    }
    
    // private static boolean isTopActivity(Context context)
    // {
    //
    // ActivityManager activityManager = (ActivityManager)
    // context.getSystemService(Context.ACTIVITY_SERVICE);
    //
    // List<RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(1);
    //
    // if (tasksInfo.size() > 0)
    // {
    // if (context.getPackageName()
    // .equals(tasksInfo.get(0).topActivity.getPackageName()))
    // {
    // return true;
    // }
    // }
    // return false;
    // }
    
    /**
     * 程序是否在前台运行
     * 
     * @return [参数说明]
     * @return boolean [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public static boolean isAppOnForeground(Context context)
    {
        ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (appProcesses == null)
            return false;
        
        for (RunningAppProcessInfo appProcess : appProcesses)
        {
            // The name of the process that this object is associated with.
            if (appProcess.processName.equals(DXApplication.getContext().getPackageName())
                && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
            {
                // int[] pid = { appProcess.pid };
                // Debug.MemoryInfo[] memoryInfo =
                // activityManager.getProcessMemoryInfo(pid);
                // int memSize = memoryInfo[0].dalvikPrivateDirty;
                return true;
            }
        }
        
        return false;
    }
    
    public static void sysoMemoryInfo(Context context)
    {
        ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        
        for (RunningAppProcessInfo appProcess : appProcesses)
        {
            if (appProcess.processName.equals(DXApplication.getContext().getPackageName()))
            {
                int[] pid = {appProcess.pid};
                Debug.MemoryInfo[] memoryInfo = activityManager.getProcessMemoryInfo(pid);
                
                int memSize = memoryInfo[0].dalvikPrivateDirty;
                Logger.i(appProcess.processName + "MemorySize:" + memSize + "KB");
            }
        }
    }
    
    @Override
    public void onTerminate()
    {
        Logger.d(TAG, "DXApplication onTerminate.");
        // 应用退出时，关闭服务
        if (serviceIntents != null && serviceIntents.size() != 0)
        {
            stopAppService();
        }
        
        // 应用退出时，关闭所有活动
        if (activityLists != null && activityLists.size() != 0)
        {
            for (int i = 0; i < activityLists.size(); i++)
            {
                Logger.d(TAG, activityLists.get(i).toString());
            }
            finishActivityLists();
        }
        
        super.onTerminate();
    }
    
    /**
     * An extension to Application class to provide tracker for analytics purposes. Having the tracker
     * instances here allows all the activities to access the same tracker instances. The trackers can
     * be initialised on startup or when they are required based on performance requirements.
     */
    //线上
    private static final String PROPERTY_ID = /*"UA-67694625-1"*/"UA-27877351-1";

    //线下
//    private static final String PROPERTY_ID = "UA-67694625-1"/*"UA-27877351-1"*/;

    /**
     * Enum used to identify the tracker that needs to be used for tracking.
     *
     * A single tracker is usually enough for most purposes. In case you do need multiple trackers,
     * storing them all in Application object helps ensure that they are created only once per
     * application instance.
     */
    public enum TrackerName
    {
        APP_TRACKER, // Tracker used only in this app.
        GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg: roll-up tracking.
        ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a company.
    }
    
    HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();
    
    /**  
     * 获取所请求的跟踪器
     * @param trackerId 
     * @return
     * @see [类、类#方法、类#成员]
     */
    public synchronized Tracker getTracker(TrackerName trackerId)
    {
        if (!mTrackers.containsKey(trackerId))
        {
            GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
            Tracker t =
                (trackerId == TrackerName.APP_TRACKER) ? analytics.newTracker(PROPERTY_ID)
                    : (trackerId == TrackerName.GLOBAL_TRACKER) ? analytics.newTracker(R.xml.global_tracker)
                        : analytics.newTracker(R.xml.ecommerce_tracker);
            mTrackers.put(trackerId, t);
        }
        return mTrackers.get(trackerId);
    }
    
}
